package ${cfg.parent}.${package.ModuleName}.query;

import java.util.List;
import java.util.ArrayList;
import java.util.Optional;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.justgame.project.cloud.common.query.Column;
import com.justgame.project.cloud.common.query.BaseSelectBuilder;
import com.justgame.project.cloud.common.query.AbstractQueryWrapper;
import com.justgame.project.cloud.common.query.Query;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import ${cfg.parent}.${package.ModuleName}.entity.${table.entityName};
<#assign imports=cfg.tool.getQueryTemplateImports(cfg.entity)>
<#list imports as import>
${import}
</#list>
import ${cfg.parent}.${package.ModuleName}.wrapper.${table.entityName}Wrapper;

public class ${table.entityName}Query extends AbstractQueryWrapper<${table.entityName}, MPJLambdaWrapper<${table.entityName}>, ${table.entityName}Wrapper> {

    private ${table.entityName}Query() {
        super(new MPJLambdaWrapper<>(${table.entityName}.class,"${table.name}"));
    }

    public static ${table.entityName}Query builder(){
        return new ${table.entityName}Query();
    }

    public static class Select{

        private final List<Query> queries;

        protected Select(){
            queries = new ArrayList<>();
        }

        protected Select(List<Query> queries) {
            this.queries = queries;
        }

        public Query[] getQueriesArray() {
            return queries.toArray(new Query[0]);
        }

        public static SelectBuilder builder(){
            return new SelectBuilder();
        }

        public Query[] build(){
            return queries.toArray(new Query[0]);
        }

        public static class SelectBuilder extends BaseSelectBuilder {
            public SelectBuilder ${table.entityName}(){
                return ${table.entityName}(Column.all());
            }

            public SelectBuilder ${table.entityName}(Column column){
                return add(Query.builder(${table.entityName}.class)
                            .selectColumns(column)
                            .build());
            }
            <#if cfg.entity??>
                <#list cfg.entity.joinTables as joinTable>

            public SelectBuilder ${joinTable.alias}(){
                return <#if joinTable.alias??>${joinTable.alias}<#else>${joinTable.targetEntity.name}</#if>(Column.all());
            }

            public SelectBuilder ${joinTable.alias}(Column column){
                return <#if joinTable.alias??>${joinTable.alias}<#else>${joinTable.targetEntity.name}</#if>(column, null);
            }

            public SelectBuilder ${joinTable.alias}(Column column,${joinTable.targetEntity.name}Query.Select selectQuery){
                return <#if joinTable.alias??>${joinTable.alias}<#else>${joinTable.targetEntity.name}</#if>("${joinTable.alias}Wrapper", column, null);
            }

            public SelectBuilder ${joinTable.alias}(String mappingName,Column column,${joinTable.targetEntity.name}Query.Select selectQuery){
                return add(Query.builder(${joinTable.targetEntity.name}.class)
                            .mapping(mappingName)
                            .leftOn((SFunction<${joinTable.targetEntity.name},?>)${joinTable.targetEntity.name}::get${joinTable.targetEntityField.name?cap_first})
                            .rightOn((SFunction<${joinTable.sourceEntity.name},?>)${joinTable.sourceEntity.name}::get${joinTable.sourceEntityField.name?cap_first})
                            .selectColumns(column)
                            .join(Optional.ofNullable(selectQuery).map(${joinTable.targetEntity.name}Query.Select::getQueriesArray).orElse(null))
                            .build());
            }
                </#list>
            </#if>

            public Select build(){
                return new Select(getQueries());
            }
        }

    }
}